#include "ChatMessageTask.h"
#include "TcpConnection.h"
#include "MessageCodec.h"
#include "ConnectionManager.h"
#include "block_log.h"
#include "ConnectPool.h"
#include "Connect.h"
#include <chrono>

ChatMessageTask::ChatMessageTask(TcpConnection* conn, const std::string& jsonBody)
    : m_conn(conn), m_jsonBody(jsonBody)
{
}

void ChatMessageTask::work(void* arg)
{
    Debug("ChatMessageTask 开始处理聊天消息");
    
    // 步骤1: 解析消息
    auto msgOpt = MessageCodec::textMessageFromJson(m_jsonBody);
    if (!msgOpt) {
        Debug("聊天消息解析失败");
        return;
    }
    
    TextMessage msg = msgOpt.value();
    
    // 验证发送者ID（必须是当前登录用户）
    if (!m_conn->isLoggedIn()) {
        Debug("用户未登录，拒绝发送消息");
        return;
    }
    
    uint64_t actualSenderId = m_conn->getUserId();
    if (msg.sender_id != actualSenderId) {
        Debug("发送者ID不匹配：声称 %lu，实际 %lu", msg.sender_id, actualSenderId);
        msg.sender_id = actualSenderId;  // 强制使用真实ID
    }
    
    // 设置时间戳（使用服务器时间，防止客户端篡改）
    msg.timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now().time_since_epoch()
    ).count();
    
    Debug("收到聊天消息 - 发送者: %lu, 接收者: %lu, 内容: %s",
          msg.sender_id, msg.receiver_id, msg.content.c_str());
    
    // 步骤2: 保存消息到数据库（用于历史记录和离线消息）
    try {
        auto connPool = ConnectionPool::getConnectionPool();
        auto dbConn = connPool->getConnection();
        
        if (dbConn) {
            sql::Connection* conn = dbConn->getConnection();
            
            std::unique_ptr<sql::PreparedStatement> pstmt(
                conn->prepareStatement(
                    "INSERT INTO messages (from_user_id, to_user_id, content, message_type, is_read) "
                    "VALUES (?, ?, ?, 0, 0)"
                )
            );
            
            pstmt->setUInt64(1, msg.sender_id);
            pstmt->setUInt64(2, msg.receiver_id);
            pstmt->setString(3, msg.content);
            
            pstmt->executeUpdate();
            Debug("消息已保存到数据库");
        }
    } catch (const sql::SQLException& e) {
        Debug("保存消息到数据库失败: %s (错误码: %d)", e.what(), e.getErrorCode());
        // 即使保存失败，也继续转发消息
    }
    
    // 步骤3: 转发消息给接收者（如果在线）
    Debug("开始查找接收者 %lu 的连接...", msg.receiver_id);
    TcpConnection* receiverConn = ConnectionManager::getInstance()->getConnection(msg.receiver_id);
    
    if (receiverConn) {
        // 接收者在线，转发消息
        Debug("接收者 %lu 在线，准备转发消息", msg.receiver_id);
        auto messageData = MessageCodec::encode(msg);
        Debug("消息已编码，长度: %zu 字节", messageData.size());
        
        receiverConn->sendResponseAsync(messageData);
        Debug("✓ 消息已转发给在线用户 %lu (内容: %s)", msg.receiver_id, msg.content.c_str());
    } else {
        // 接收者离线，消息已保存到数据库，等待用户上线后拉取
        Debug("✗ 接收者 %lu 离线，消息已保存为离线消息", msg.receiver_id);
        
        // 打印当前所有在线用户（调试用）
        auto onlineUsers = ConnectionManager::getInstance()->getOnlineUsers();
        Debug("当前在线用户数: %zu", onlineUsers.size());
        for (auto uid : onlineUsers) {
            Debug("  - 在线用户: %lu", uid);
        }
    }
    
    // 步骤4: 可选 - 给发送者发送确认（表示消息已送达服务器）
    // 这里可以定义一个 MESSAGE_ACK 协议
    
    Debug("ChatMessageTask 处理完成");
}

